package com.yuexiang.melodyhub.authserver.controller;

import com.google.code.kaptcha.Producer;
import com.yuexiang.melodyhub.authserver.dto.OAuthKaptCha.response.OAuthKaptChaResponse;
import com.yuexiang.melodyhub.authserver.feign.ThirdPartyFeignService;
import com.yuexiang.melodyhub.common.constant.UsualConstant.BizConstant;
import com.yuexiang.melodyhub.common.dto.thirdParty.EmailSendEmail.response.EmailSendEmailResponse;
import com.yuexiang.melodyhub.common.exception.gateway.UnavailableServiceException;
import com.yuexiang.melodyhub.common.result.ResultData;
import com.yuexiang.melodyhub.common.result.ReturnCode;
import com.yuexiang.melodyhub.common.utils.VerificationUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/oauth")
public class KaptChaController {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private Producer producer;

    @Autowired
    private ThirdPartyFeignService thirdPartyFeignService;

    @GetMapping("/email")
    public ResultData<EmailSendEmailResponse> getEmail(@RequestParam("receiver") String receiver) {
        String redisCode = (String) redisTemplate.opsForValue().get(BizConstant.EMAIL_CODE_CACHE_PREFIX + receiver);
        if (StringUtils.hasLength(redisCode)) {
            long l = Long.parseLong(redisCode.split("_")[1]);
            if (System.currentTimeMillis() - l < BizConstant.EMAIL_CODE_CACHE_EXPIRE_MS) {
                return ResultData.fail(ReturnCode.EMAIL_CODE_EXCEPTION.getCode(), ReturnCode.EMAIL_CODE_EXCEPTION.getMsg());
            }
        }

        try {
            String code = VerificationUtil.generateVerificationCode();
            ResultData<EmailSendEmailResponse> res = thirdPartyFeignService.sendEmail(receiver, code, BizConstant.EMAIL_CODE_CACHE_EXPIRE_MINUTES);
            redisTemplate.opsForValue().set(BizConstant.EMAIL_CODE_CACHE_PREFIX + receiver, code + "_" + System.currentTimeMillis(), BizConstant.EMAIL_CODE_CACHE_EXPIRE_MINUTES, TimeUnit.MINUTES);
            return res;
        } catch (Exception e) {
            throw new UnavailableServiceException();
        }
    }

    @GetMapping("/kaptcha")
    public ResultData<OAuthKaptChaResponse> getKaptCha() throws IOException {
        String key = UUID.randomUUID().toString();
        String code = producer.createText();

        BufferedImage image = producer.createImage(code);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(image, "jpg", outputStream);

        Base64.Encoder encoder = Base64.getEncoder();
        String baseImage = "data:image/jepg;base64," + encoder.encodeToString(outputStream.toByteArray());

        redisTemplate.opsForHash().put(BizConstant.CAPTCHA_KEY, key, code);
        redisTemplate.expire(BizConstant.CAPTCHA_KEY, BizConstant.CAPTCHA_EXPIRE_TIME_MINUTES, TimeUnit.MINUTES);
        return ResultData.success(OAuthKaptChaResponse.builder().key(key).img(baseImage).build());
    }
}
